﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SampleDataTools
{
    public partial class NewTabForm : DevComponents.DotNetBar.OfficeForm
    {
        static readonly private string CONFIG_FILE_NAME = "config.cfg";
        private NgxuCommand SaveResultCommand;
        private NgxuCommand ConfigCommand;

        private ChartControl2x2 chart;
        private Config mainConfig;
        private UDPWork worker;

        private List<LightDisplayArea> lightDisplayAreas;
        private List<DisplayArea> displayAreas;

        public NewTabForm()
        {
            InitializeComponent();

            lightDisplayAreas = new List<LightDisplayArea>();
            displayAreas = new List<DisplayArea>();
        }

        public void AddNgxuCommand(NgxuCommand command)
        {
            if (command != null)
            {
                DevComponents.DotNetBar.ButtonX button = new DevComponents.DotNetBar.ButtonX();
                button.Height = 51;
                if (commandFlowLayoutPanel.Controls.Count == 0)
                {
                    button.Width = 100;
                }
                else
                {
                    button.Anchor = AnchorStyles.Left | AnchorStyles.Right;
                }
                button.Tag = command;
                button.Symbol = command.Symbol;
                button.Text = command.Title;
                button.Name = command.Title;
                button.Enabled = command.Enabled;
                button.Visible = command.Visible;

                button.AccessibleRole = System.Windows.Forms.AccessibleRole.PushButton;
                button.ColorTable = DevComponents.DotNetBar.eButtonColor.OrangeWithBackground;
                button.Style = DevComponents.DotNetBar.eDotNetBarStyle.StyleManagerControlled;
                button.SymbolSet = DevComponents.DotNetBar.eSymbolSet.Material;

                button.Click += (sender, e) =>
                {
                    command.Execute();
                };

                command.SymbolChanged += (sender, e) =>
                {
                    if (InvokeRequired)
                    {
                        this.Invoke(new CrossAppDomainDelegate(() =>
                       {
                           button.Symbol = command.Symbol;
                       }));
                    }
                    else
                    {
                        button.Symbol = command.Symbol;
                    }
                };

                command.TitleChanged += (sender, e) =>
                {

                    if (InvokeRequired)
                    {
                        this.Invoke(new CrossAppDomainDelegate(() =>
                        {
                            button.Text = command.Title;
                            button.Name = command.Title;
                        }));
                    }
                    else
                    {
                        button.Text = command.Title;
                        button.Name = command.Title;
                    }
                };

                command.EnabledChanged += (sender, e) =>
                {

                    if (InvokeRequired)
                    {
                        this.Invoke(new CrossAppDomainDelegate(() =>
                        {
                            button.Enabled = command.Enabled;
                        }));
                    }
                    else
                    {
                        button.Enabled = command.Enabled;
                    }
                };

                command.VisibleChanged += (sender, e) =>
                {

                    if (InvokeRequired)
                    {
                        this.Invoke(new CrossAppDomainDelegate(() =>
                        {
                            button.Visible = command.Visible;
                        }));
                    }
                    else
                    {
                        button.Visible = command.Visible;
                    }
                };

                command.BackColorChanged += (sender, e) =>
                {
                    if (InvokeRequired)
                    {
                        this.Invoke(new CrossAppDomainDelegate(() =>
                        {
                            button.BackColor = command.BackColor;
                        }));
                    }
                    else
                    {
                        button.BackColor = command.BackColor;
                    }
                };

                command.ForeColorChanged += (sender, e) =>
                {
                    if (InvokeRequired)
                    {
                        this.Invoke(new CrossAppDomainDelegate(() =>
                        {
                            button.ForeColor = command.ForeColor;
                        }));
                    }
                    else
                    {
                        button.ForeColor = command.ForeColor;
                    }
                };


                commandFlowLayoutPanel.Controls.Add(button);

                //if (groupPanel1.Visible == false)
                //{
                //    this.Controls.Remove(groupPanel1);
                //    groupPanel1.Visible = true;
                //    this.Controls.Add(groupPanel1);
                //}
            }
        }

        public void RemoveNgxuCommand(NgxuCommand command)
        {
            foreach (Control c in commandFlowLayoutPanel.Controls)
            {
                if (string.Equals(c.Name, command.Title))
                {
                    commandFlowLayoutPanel.Controls.Remove(c);
                    break;
                }
            }
        }

        private void TabForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            DialogResult res = MessageBox.Show(this,
                "是否退出?",
                "提示",
                MessageBoxButtons.YesNo);
            if (res == DialogResult.No)
            {
                e.Cancel = true;
            }
            else
            {
                DialogResult = res;
            }
        }

        public System.Windows.Forms.Timer CreateTimer()
        {
            return new System.Windows.Forms.Timer(this.components);
        }

        public DialogResult Run()
        {
            Application.Run(this);
            return this.DialogResult;
        }

        public void SetCaption(string name)
        {
            this.Text = name;
        }

        private void NewTabForm_Load(object sender, EventArgs e)
        {
            worker = new UDPWork();
            mainConfig = Config.LoadFile(CONFIG_FILE_NAME);
            if (mainConfig == null)
            {
                mainConfig = new Config()
                {
                    ChartGroupConfig = new ChartGroupConfig()
                };
                InitTestConfig();
            }

            InitCommand();
            InitChart();
            InitValueDisplayArea();

            Start();
        }

        private void InitTestConfig()
        {
            mainConfig.ChartGroupConfig.Items = new ChartConfig[]
              {
                new ChartConfig()
                {
                     Name = "A",
                      DataIndex = 0,
                       Items = new ChartItemConfig[]
                       {
                           new ChartItemConfig()
                           {
                                Index = 1,
                                 Title ="X"
                           }
                       }
                },

                new ChartConfig()
                {
                     Name = "B",
                      DataIndex = 0,
                       Items = new ChartItemConfig[]
                       {
                           new ChartItemConfig()
                           {
                                Index = 1,
                                 Title ="X"
                           },
                           new ChartItemConfig()
                           {
                                Index = 2,
                                 Title ="Y"
                           }
                       }
                },

                new ChartConfig()
                {
                     Name = "C",
                      DataIndex = 0,
                       Items = new ChartItemConfig[]
                       {
                           new ChartItemConfig()
                           {
                                Index = 3,
                                 Title ="D"
                           }
                       }
                },

                new ChartConfig()
                {
                     Name = "D",
                      DataIndex = 0,
                       Items = new ChartItemConfig[]
                       {
                           new ChartItemConfig()
                           {
                                Index = 4,
                                 Title ="e"
                           }
                       }
                }
              };

            mainConfig.Items = new ItemConfig[]
            {
                new ItemConfig()
                {
                     Count = 2, Name ="abc", Port = 4466, WriteFileName = "ABC.dat"
                }
            };

            thresholdFlowLayoutPanel.Controls.Add(new LightDisplayArea());
            thresholdFlowLayoutPanel.Controls.Add(new LightDisplayArea());
            thresholdFlowLayoutPanel.Controls.Add(new LightDisplayArea());
            thresholdFlowLayoutPanel.Controls.Add(new LightDisplayArea());
            thresholdFlowLayoutPanel.Controls.Add(new LightDisplayArea());
            thresholdFlowLayoutPanel.Controls.Add(new LightDisplayArea());
            thresholdFlowLayoutPanel.Controls.Add(new LightDisplayArea());
            thresholdFlowLayoutPanel.Controls.Add(new LightDisplayArea());



            valueFlowLayoutPanel.Controls.Add(new DisplayArea());
            valueFlowLayoutPanel.Controls.Add(new DisplayArea());
            valueFlowLayoutPanel.Controls.Add(new DisplayArea());
            valueFlowLayoutPanel.Controls.Add(new DisplayArea());
            valueFlowLayoutPanel.Controls.Add(new DisplayArea());
            valueFlowLayoutPanel.Controls.Add(new DisplayArea());
            valueFlowLayoutPanel.Controls.Add(new DisplayArea());
        }

        public void InitCommand()
        {
            //StartDataLogCommand = new NgxuCommand(OnStartDataLogClick)
            //{
            //    Title = "Start Log",
            //    Symbol = "57399"
            //};
            //AddNgxuCommand(StartDataLogCommand);

            //StopDataLogCommand = new NgxuCommand(OnStopDataLogClick)
            //{
            //    Title = "Stop Log",
            //    Symbol = "57415"
            //};
            //AddNgxuCommand(StopDataLogCommand);

            SaveResultCommand = new NgxuCommand(OnSaveCommandClick)
            {
                Title = "Save Result",
                Symbol = "59485"
            };
            AddNgxuCommand(SaveResultCommand);

            ConfigCommand = new NgxuCommand(OnConfigClick)
            {
                Title = "Config",
                Symbol = "59550"

            };
            AddNgxuCommand(ConfigCommand);
        }

        private void OnConfigClick(object sender, EventArgs e)
        { 
            var c = mainConfig.Clone();
            PropertyForm f = new PropertyForm();
            f.PropertyValue = c;
            if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                Config newConfig = f.PropertyValue as Config;
                if (ValidateConfig(newConfig))
                {
                    Stop();

                    mainConfig.Items = newConfig.Items;
                    mainConfig.ThresholdValueItemConfigs = newConfig.ThresholdValueItemConfigs;
                    mainConfig.ValueItemConfigs = newConfig.ValueItemConfigs;

                    InitValueDisplayArea();
                    Start();
                }
            }
        }

        private bool ValidateConfig(Config newConfig)
        {
            bool res = true;
            if (null != newConfig)
            {
                try
                {
                    newConfig.Items?.ToDictionary(x => x.Port);
                }
                catch(Exception)
                {
                    res = false;
                    MessageBox.Show("输入的端口号重复");
                }
            }

            return res;
        }

        private void OnSaveCommandClick(object sender, EventArgs e)
        {
            worker.ClearTempDirectory();
            Stop();

            FolderBrowserDialog dlg = new FolderBrowserDialog();
            if (dlg.ShowDialog(this) == DialogResult.OK)
            {
                worker.CopyToDir(dlg.SelectedPath);
            }
            Start();
        }

        private void Stop()
        {
            updateTimer.Stop();
            worker.Stop();
        }

        private void Start()
        {
            worker.Start(mainConfig.Items);
            chart.ClearSeries();
            updateTimer.Start();
        }
        
        public void InitChart()
        {
            chart = new ChartControl2x2();
            chart.Config = mainConfig.ChartGroupConfig;
            chart.Dock = System.Windows.Forms.DockStyle.Fill;

            splitContainer1.Panel1.Controls.Add(chart);

            chart.SetupSeries();
        }

        public void InitValueDisplayArea()
        {
            thresholdFlowLayoutPanel.Controls.Clear();
            valueFlowLayoutPanel.Controls.Clear();
            displayAreas.Clear();
            lightDisplayAreas.Clear();

            if (mainConfig.ValueItemConfigs != null)
            {
                foreach (var item in mainConfig.ValueItemConfigs)
                {
                    DisplayArea display = new DisplayArea();
                    display.SetConfig(item);
                    displayAreas.Add(display);
                }
            }
            valueFlowLayoutPanel.Controls.AddRange(displayAreas.ToArray());

            if (mainConfig.ThresholdValueItemConfigs != null)
            {
                foreach (var item in mainConfig.ThresholdValueItemConfigs)
                {
                    LightDisplayArea display = new LightDisplayArea();
                    display.SetConfig(item);
                    lightDisplayAreas.Add(display);
                }
            }
            thresholdFlowLayoutPanel.Controls.AddRange(lightDisplayAreas.ToArray());


        }

        private void NewTabForm_FormClosed(object sender, FormClosedEventArgs e)
        {
            Stop();
            mainConfig?.Save(CONFIG_FILE_NAME);
        }

        private void UpdateTimer_Tick(object sender, EventArgs e)
        {
            var datas = worker.GetBuffDatas();
            if (datas != null)
            {
                chart.Update(datas);
                foreach (var item in displayAreas)
                {
                    item.Update(datas);
                }
                foreach (var item in lightDisplayAreas)
                {
                    item.Update(datas);
                }
            }
        }
    }
}
